﻿using System.Text;
using System.Collections.Generic;


namespace FuzzScript
{
    /// <summary>
    /// Interface that must be implemented by all system nodes
    /// </summary>
    public interface INode
    {
        double Execute();
        void AddSibling(INode p_SiblingNode);
        string Generate();
        string Name { get; set; }
        List<INode> Siblings { get; }
    }

    /// <summary>
    /// Interface implemented by all nodes that can return a dom
    /// </summary>
    public interface IDOMValueNode
    {
        double DOMValue { get; }
    }

    /// <summary>
    /// Nodes base class. each node will contain a list of siblings
    /// </summary>
    public class Node : INode
    {
        /// <summary>
        /// List of the Sibling Nodes connected to the node
        /// </summary>
        protected List<INode> m_SiblingNodes;

        /// <summary>
        /// Contructor
        /// </summary>
        internal Node()
        {
            m_SiblingNodes = new List<INode>();
        }

        /// <summary>
        /// gets a list of siblings connected to the node
        /// </summary>
        public List<INode> Siblings
        {
            get
            {
                return m_SiblingNodes;
            }
        }

        /// <summary>
        /// The name of the node
        /// </summary>
        protected string m_sName;

        /// <summary>
        /// gets or sets the name of the node
        /// </summary>
        public string Name
        {
            get { return m_sName; }
            set { m_sName = value; }
        }

        /// <summary>
        /// Executes all the sibling nodes
        /// </summary>
        /// <returns></returns>
        public virtual double Execute()
        {
            for (int i = 0; i < m_SiblingNodes.Count; i++)
            {
                m_SiblingNodes[i].Execute();
            }
            return 0D;
        }

        /// <summary>
        /// Adds a new sibling node
        /// </summary>
        /// <param name="p_SiblingNode">new sibling</param>
        public virtual void AddSibling(INode p_SiblingNode)
        {
            m_SiblingNodes.Add(p_SiblingNode);
        }

        /// <summary>
        /// Generates the node equivalent in c# code
        /// </summary>
        /// <returns></returns>
        public virtual string Generate()
        {
            StringBuilder sCode = new StringBuilder();

            for (int i = 0; i < m_SiblingNodes.Count; i++)
            {

                sCode.Append(m_SiblingNodes[i].Generate());
            }
            return sCode.ToString();
        }

        public override string ToString()
        {
            StringBuilder builder = new StringBuilder();

            for (int i = 0; i < m_SiblingNodes.Count; i++)
            {
                builder.Append("\n\r");
                builder.Append(m_SiblingNodes[i].ToString());
            }
            return builder.ToString();
        }
    }
}
